
/*
 * MODULE  NAME  :
 * PROGRAM NAME  : net.h
 * AUTHOR        : hotmocha(hotmocha@126.com)
 * CREATE  DATE  : 2015-10-21 08:49:53
 * PROGRAM DESC  :
 *
 * HISTORY       :
 *
 */
#ifndef _H_NET_H_
#define _H_NET_H_

#include <sys/select.h>
#include <sys/time.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <unistd.h>

#include "constants.h"

#define EVENT_LOCAL_ERROR	1
#define EVENT_REMOTE_CLOSE	2
#define EVENT_READ		4
#define EVENT_WRITE		8
#define EVENT_ERROR		16

#define CUSTOM_SOCKET_TYPE_DEFAULT      0
#define CUSTOM_SOCKET_TYPE_LISTEN       1
#define CUSTOM_SOCKET_TYPE_INPUT        2

struct select_env;
struct custom_socket;

typedef int (*after_connect_entry)(struct select_env *env, struct custom_socket *s);
typedef int (*event_handler)(struct select_env *env, struct custom_socket *s, int event_type);

struct select_env {
	fd_set readfds;
	fd_set writefds;
	fd_set errorfds;
	
	struct timeval timeout;
	int maxfd_plus_1;
	struct custom_socket **sockets_array;

	after_connect_entry after_connect;
};

struct net_addr {
	int port;
	char ipv4[IPV4LEN];
        struct sockaddr_in sockaddr;
};

struct custom_socket {
        int sockfd;
        struct net_addr addr;	/* local address info */
	void* event;
	event_handler handler;
	int type;	/* listen or default or input */
	
	void *ptr;		/* point to own struct(tk_connect) */
	void *pv;               /* custom data or point to a function */
};


void set_epoll_after_connect(struct select_env *env, after_connect_entry after_connect);

int select_process_events(struct select_env* env, long timeout);

void set_event_data(void *pv, void *data);
void* get_event_data(void *pv);
int set_custom_socket_addr_info_by_sockfd(struct custom_socket* s, int sockfd);

struct custom_socket* get_custom_socket(int sockfd);
void destory_custom_socket(struct select_env *env, struct custom_socket *s);
int insert_custom_socket(struct select_env *env, struct custom_socket *s);
int delete_custom_socket(struct select_env *env, struct custom_socket *s);

void set_select_env_timeout(struct select_env *env, int millseconds);
struct select_env* create_select_env(after_connect_entry after_connect);

int select_set_event(struct select_env* env, int type, void *event);
void* get_custom_socket_pv(struct custom_socket *s);
void set_custom_socket_pv(struct custom_socket *s, void *pv);

#endif
